﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class GUIPoolManager : MonoBehaviour {

	public Transform HexPrefab;
	public Transform GUIHexPrefab;
	public GUIText GUIMessage;
	public GUIText GUITeamTitle;
	public GUIText GUIUnitsValue;
	public GUIText GUIPowerValue;
	public Vector2 HexOffset;
	public int RowSize = 5;
	
	private List<Transform> pieces; //units in pool
	private int piecesCount = 0;
	
	private List<Transform> teamPieces; //units in team
	private int teamSize = 0;
	
	private Vector3 initPosition; //position of topleft element
	
	private GameHex selectedHex; //selected unit/powerup in pool
	private GUIHex selectedTeamHex = null; //selected unit/powerup in team
	
	private Rect rectNewUnit = new Rect(0,0,100,50);
	private Rect rectNewPowerUp = new Rect(0,50,100,50);
	private Rect rectDelete = new Rect(0,100,100,50);
	private Rect rectLevelUp = new Rect(0,150,50,50); //+
	private Rect rectLevelDown = new Rect(50,150,50,50); //-
	//Skill
	private Rect rectSetSkill = new Rect(0,200,100,50);
	private Rect rectLevelUpSkill = new Rect(0,250,50,50); //+
	private Rect rectLevelDownSkill = new Rect(50,250,50,50); //-
	//PowerUp
	private Rect rectSetPowerUp = new Rect(0,300,100,50); //
	
	private Rect rectNewTeam = new Rect(100,0,100,50);
	private Rect rectDeleteTeam = new Rect(100,50,100,50);
	private Rect rectTeamAddUnit = new Rect(100,100,100,50);
	private Rect rectTeamRemoveUnit = new Rect(100,150,100,50);
	private Rect rectResetTeam = new Rect(100,200,100,50);
	
	private Rect rectSaveUnits = new Rect(0,450,100,50);
	
	private Rect rectStartMatch;
	private Rect rectEditBoard;
	private Rect rectEnemyTeam;
	private Rect rectPrevTeam;
	private Rect rectNextTeam;
	
	// Use this for initialization
	void Start () {
		initPosition = HexPrefab.position;
		HexPrefab.gameObject.SetActive(false);
		GUIHexPrefab.gameObject.SetActive(false);
		
		rectStartMatch = new Rect(Screen.width-100,0,100,50);
		rectEditBoard = new Rect(Screen.width-100,50,100,50);
		
		rectEnemyTeam = new Rect(Screen.width-100,350,100,50);
		rectPrevTeam = new Rect(Screen.width-100,400,100,50);
		rectNextTeam = new Rect(Screen.width-100,450,100,50);
				
		pieces = new List<Transform>();
		piecesCount = 0;
		teamPieces = new List<Transform>();
		teamSize = 0;
		GUIMessage.text = "";
		
		//load or initialize game pool
		GamePool loadedPool = null;
		GameSaveLoad.LoadPool(out loadedPool);
		if (loadedPool != null) {
			GamePool.playerPool = loadedPool;
		}
		
		//initialize game team
		if (GamePool.playerPool.teams.Count == 0) {
			GamePool.currentTeam = new GameTeam();
			GamePool.playerPool.teamIndex = 0;
			GamePool.playerPool.teams.Add(GamePool.currentTeam);
		}
		
		Refresh();
	}
	
	// Update is called once per frame
	void Update () {
		// allow selecting a piece in Team panel
		if (CheckSelectTeamHex())
			return;
	
		Vector2 touchPos;
		#if UNITY_EDITOR || UNITY_STANDALONE_WIN
		if (Input.GetMouseButtonDown (0)) {
			touchPos = Input.mousePosition;
		#else
		if (Input.touchCount > 0 &&
		    Input.GetTouch(0).phase == TouchPhase.Began) {
			touchPos = Input.GetTouch(0).position;
		#endif
			Debug.Log("GameManager.Update : touchPos=" + touchPos);
			//get the projected position on the ground
			Ray ray = Camera.main.ScreenPointToRay(touchPos);
			RaycastHit hitInfo;
			if (Physics.Raycast(ray, out hitInfo)) {
				//check if hit object has a GameHex
				if (selectedHex)
					selectedHex.SetColor(PlayerColor.Blue);
					
				GameHex hex = hitInfo.collider.GetComponent<GameHex>();
				if (hex != null) {
					selectedHex = hex;
					selectedHex.SetColor(PlayerColor.Red);
					//Debug.Log("SelectedHex.unit=" + selectedHex.getUnit() + ",powerup=" + selectedHex.getPowerUp());
				}
				else
					selectedHex = null;
			}
		}
	}
	
	// Management options
	void OnGUI() {
		if (GUI.Button(rectNewUnit, "New Unit")) {
			//create basic unit in pool
			GameUnit unit = new GameUnit(); //create in pool
			unit.level = 1;
			GamePool pool = GamePool.playerPool;
			pool.units.Add(unit);
			GameHex hex = createPiece(); //create in scene
			hex.setUnit(unit);
		}
		
		if (GUI.Button(rectNewPowerUp, "New PowerUp")) {
			GamePowerUp powerUp = new GamePowerUp(); //create object
			powerUp.power++;
			powerUp.level = 1;
			GameHex hex = createPiece(); //create in scene
			hex.setPowerUp(powerUp);
		}
		
		if (GUI.Button(rectDelete, "Delete")) {
			if (selectedHex != null) {
				GameUnit unit = selectedHex.getUnit();
				GamePool pool = GamePool.playerPool; //remove from pool
				pool.units.Remove(unit);
				removePiece(selectedHex); //remove from scene
				Refresh();
			}
		}
		
		if (GUI.Button(rectLevelUp, "Level+")) {
			if (selectedHex != null) {
				GameUnit unit = selectedHex.getUnit();
				if (unit != null) {
					unit.level++;
					selectedHex.setUnit(unit); //refresh in scene
				}
				else {
					GamePowerUp powerUp = selectedHex.getPowerUp();
					powerUp.level++;
					selectedHex.setPowerUp(powerUp);
				}
				RefreshTeam();
			}
		}
		
		if (GUI.Button(rectLevelDown, "Level-")) {
			if (selectedHex != null) {
				GameUnit unit = selectedHex.getUnit();
				if (unit != null) {
					if (unit.level > 1) {
						unit.level--;
						selectedHex.setUnit(unit); //refresh in scene
						RefreshTeam();
					}
				}
				else {
					GamePowerUp powerUp = selectedHex.getPowerUp();
					if (powerUp.level > 1) {
						powerUp.level--;
						selectedHex.setPowerUp(powerUp);
						RefreshTeam();
					}
				}
			}
		}
		
		if (GUI.Button (rectSetSkill, "Skill+")) {
			if (selectedHex != null) {
				GameUnit unit = selectedHex.getUnit();
				if (unit != null) {
					unit.skill++;
					if (unit.skill == GameSkill.MaxSkills) {
						unit.skill = GameSkill.None; //cycle
						unit.skillLevel = 0;
					}
					else
						unit.skillLevel = 1;
						
					selectedHex.setUnit(unit); //refresh in scene
					RefreshTeam();
				}
			}
		}
		
		if (GUI.Button(rectLevelUpSkill, "Level+")) {
			if (selectedHex != null) {
				GameUnit unit = selectedHex.getUnit();
			 	if (unit != null && unit.skill != GameSkill.None) {
					selectedHex.getUnit().skillLevel++;
					selectedHex.setUnit(unit);
					RefreshTeam();
				}
			}
		}
		
		if (GUI.Button(rectLevelDownSkill, "Level-")) {
			if (selectedHex != null) {
				GameUnit unit = selectedHex.getUnit();
				if (unit != null && unit.skill != GameSkill.None && unit.skillLevel > 1) {
					selectedHex.getUnit().skillLevel--;
					selectedHex.setUnit(unit);
					RefreshTeam();
				}
			}
		}
		
		if (GUI.Button(rectSetPowerUp, "PowerUp+")) {
			if (selectedHex != null && selectedHex.getPowerUp() != null) {
				GamePowerUp powerUp = selectedHex.getPowerUp();
				powerUp.power++;
				//Debug.Log("PowerUp.power=" + powerUp.power);
				if (powerUp.power == GamePower.MaxPowerUps) {
					powerUp.power = GamePower.None;
					powerUp.power++;
				}
				selectedHex.setPowerUp(powerUp); //refresh in scene
				RefreshTeam();
			}
		}
		
		if (GUI.Button (rectNewTeam, "New Team")) {
			GameTeam team = new GameTeam();
			GamePool.playerPool.teams.Add(team);
			GamePool.playerPool.teamIndex = GamePool.playerPool.teams.Count - 1; //last
			GamePool.currentTeam = team;
			RefreshTeam();
		}
		
		if (GUI.Button (rectDeleteTeam, "Delete Team")) {
			GamePool pool = GamePool.playerPool;
			if (pool.teams.Count > 1) {
				pool.teams.Remove(GamePool.currentTeam);
				if (pool.teamIndex >= pool.teams.Count) {
					pool.teamIndex = pool.teams.Count - 1;
				}
				GamePool.currentTeam = pool.teams[pool.teamIndex];
				RefreshTeam();
			}
			else
				showMessage("You need at least 1 team");
		}
		
		if (GUI.Button (rectTeamAddUnit, "Team +Unit")) {
			if (selectedHex != null) {
				//use in current team
				GameTeam team = GamePool.currentTeam;
				GameUnit unit = selectedHex.getUnit();
				if (unit != null) {
					if (!team.units.Contains(unit)) {
						team.units.Add(unit);
						RefreshTeam();
					}
					else
						showMessage("Unit is already in team!");
				}
				else {
					GamePowerUp powerUp = selectedHex.getPowerUp();
				 	if (!team.powerups.Contains(powerUp)) {
						team.powerups.Add(powerUp);
						RefreshTeam();
					}
					else
						showMessage("Powerup is already in team!");
				}
			}
		}
		
		if (GUI.Button (rectTeamRemoveUnit, "Team -Unit")) {
			//remove selected hex from current team
			if (selectedTeamHex != null) {
				GameTeam team = GamePool.currentTeam;
				GameUnit unit = selectedTeamHex.getUnit();
				if (unit != null) {
					if (team.units.Contains(unit)) {
						team.units.Remove(unit);
						RefreshTeam();
					}
				}
				else {
					GamePowerUp powerUp = selectedTeamHex.getPowerUp();
					if (team.powerups.Contains(powerUp)) {
						team.powerups.Remove(powerUp);
						RefreshTeam();
					}
				}
				selectedTeamHex.setSelected(false);
				selectedTeamHex = null;
			}
		}
		
		if (GUI.Button(rectResetTeam, "ResetTeam")) {
			//remove all units from current team
			GamePool.currentTeam.units.Clear();
			GamePool.currentTeam.powerups.Clear();
			RefreshTeam();
		}
		
		if (GUI.Button(rectEnemyTeam, "MakeEnemyTeam")) {
			GamePool.playerPool.enemyTeamIndex = GamePool.playerPool.teamIndex;
		}
		
		if (GUI.Button(rectPrevTeam, "<< Team")) {
			GamePool pool = GamePool.playerPool;
			if (pool.teamIndex > 0) {
				pool.teamIndex--;
				GamePool.currentTeam = pool.teams[pool.teamIndex];
				RefreshTeam();
			}
		}
		if (GUI.Button(rectNextTeam, "Team >>")) {
			GamePool pool = GamePool.playerPool;
				Debug.Log("pool.teamIndex = " + pool.teamIndex);
				Debug.Log("pool.teams.Count = " + pool.teams.Count);
			if (pool.teamIndex < (pool.teams.Count - 1)) {
				pool.teamIndex++;
				GamePool.currentTeam = pool.teams[pool.teamIndex];
				RefreshTeam();
			}
		}
		
		if (GUI.Button(rectSaveUnits, "Save")) {
			GameSaveLoad.SavePool(GamePool.playerPool); //persistence
			showMessage("Pool is saved");// + GameSaveLoad.SavePath);
		}
			
		if (GUI.Button(rectStartMatch, "MATCH")) {
			Application.LoadLevel("Match"); //battle
		}
		
		if (GUI.Button(rectEditBoard, "BOARD")) {
			Application.LoadLevel("Board"); //edit board
		}
	}
	
 	// when the GUI is presented, refresh the data
 	//load the contents of this from the saved units config

 	void Refresh() {
		//delete all existing pieces
 		foreach (Transform piece in pieces) {
 			Destroy(piece.gameObject);
 		}
		piecesCount = 0;
		pieces.Clear();
			
 		//populate again
		GamePool pool = GamePool.playerPool;
		foreach (GameUnit unit in pool.units) {
			GameHex hex = createPiece();
			hex.setUnit(unit);
		}
		
		RefreshTeam(); //team pieces need to be refreshed too
 	}
 	
 	void RefreshTeam() {
 		//delete all existing pieces
		foreach (Transform piece in teamPieces) {
			Destroy(piece.gameObject);
		}
		teamPieces.Clear();
		teamSize = 0;

		//sum units / powerup value
		int unitsValue = 0;
		int powerValue = 0;
			
		//populate again
		GameTeam team = GamePool.currentTeam;
		foreach (GameUnit unit in team.units) {
			GUIHex hex = createTeamPiece();
			hex.setUnit(unit);
			unitsValue += unit.level;
		}
		foreach (GamePowerUp powerUp in team.powerups) {
			GUIHex hex = createTeamPiece();
			hex.setPowerUp(powerUp);
			powerValue += powerUp.level;
		}
		
		//display which active team is this
		int teamIndex = GamePool.playerPool.teamIndex + 1;
		int teamCount = GamePool.playerPool.teams.Count;
		GUITeamTitle.text = string.Format("Team {0}/{1}", teamIndex, teamCount);
		GUIUnitsValue.text = string.Format("UnitsValue={0}", unitsValue);
		GUIPowerValue.text = string.Format("PowerUpValue={0}", powerValue);
	}

 	GameHex createPiece() {
		GameObject poolObject = (GameObject)Instantiate(HexPrefab.gameObject);
		poolObject.SetActive(true);
		int row = piecesCount / RowSize;
		int col = piecesCount % RowSize; //Debug.Log ("GUIPoolManager.createPiece : row=" + row + ", col=" + col);
		Vector3 position = initPosition + new Vector3(HexOffset.x * col, -HexOffset.y * row, 0.0f);
		poolObject.transform.position = position;
		
		pieces.Add(poolObject.transform);
		piecesCount++;
		GameHex hex = poolObject.GetComponent<GameHex>();
		hex.SetColor(PlayerColor.Blue);
		//hex.setUnit(unit);
		return hex;
 	}
 	
 	void removePiece(GameHex hex) {
		pieces.Remove(hex.transform);
		piecesCount--;
		Destroy(hex.gameObject);
	}

	GUIHex createTeamPiece() {
 		GameObject teamObject = (GameObject)Instantiate(GUIHexPrefab.gameObject);
 		teamObject.SetActive(true);
 		
		GUIHex guiHex = teamObject.GetComponent<GUIHex>();
			
 		Transform hexTransform = teamObject.transform; //add to team interface
		Vector3 position = hexTransform.position;
		float posX = (guiHex.getWidth () / Screen.width) * teamSize;
		hexTransform.position = new Vector3(posX, 0.0f, position.z);
		
		teamPieces.Add(hexTransform);
		teamSize++;
		
		return guiHex;
 	}
 	
	public bool CheckSelectTeamHex() {
		bool result = false;
		Vector2 touchPos;
		#if UNITY_EDITOR || UNITY_STANDALONE_WIN
		if (Input.GetMouseButtonDown (0)) {
			touchPos = Input.mousePosition;
		#else
		if (Input.touchCount > 0 &&
		    Input.GetTouch(0).phase == TouchPhase.Began) {
			touchPos = Input.GetTouch(0).position;
		#endif
			Debug.Log("CheckSelectHex " + this.gameObject.name + " touchPos=" + touchPos);
			
			// determine which hex was selected
			foreach (Transform hex in teamPieces) {
				GUIHex guiHex = hex.GetComponent<GUIHex>();
				if (guiHex.hitTest(touchPos)) {
					if (selectedTeamHex != null)
						selectedTeamHex.setSelected(false);
					
					guiHex.setSelected(true);
					selectedTeamHex = guiHex;
					result = true;
					break;
				}
			}
		}
		return result;
	}
		

 	void showMessage(string text) {
 		Debug.Log("GUIPoolManager.showMessage : " + text);
		GUIMessage.text = text;
 	}
}
